package com.vogue.supplymall.payment.controller;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.vogue.configs.springextend.remote.DelegateResource;
import com.vogue.gear.memory.provider.IMemProvider;
import com.vogue.sprakka.client.future.FutureWrapper;
import com.vogue.supplymall.admin.business.common.constant.CachedPayValues;
import com.vogue.supplymall.admin.business.common.constant.CachedTsPayValues;
import com.vogue.supplymall.admin.business.common.inter.bean.InterCachePayValues;
import com.vogue.supplymall.common.constant.ConstantBean;
import com.vogue.supplymall.common.domain.dto.ControllerResultInfo;
import com.vogue.supplymall.common.domain.dto.OrderDetailInfo;
import com.vogue.supplymall.common.domain.dto.OrderInfo;
import com.vogue.supplymall.order.domain.biz.OrderUpdateBiz;
import com.vogue.supplymall.order.domain.model.Order;
import com.vogue.supplymall.order.domain.model.OrderPayment;
import com.vogue.supplymall.order.domain.model.OrderSeller;
import com.vogue.supplymall.order.domain.model.OrderStatus;
import com.vogue.supplymall.order.domain.service.OrderPaymentService;
import com.vogue.supplymall.order.domain.service.OrderSellerService;
import com.vogue.supplymall.order.domain.service.OrderService;
import com.vogue.supplymall.payment.api.WuXiangPayment;
import com.vogue.supplymall.payment.dto.BaseResultParameter;
import com.vogue.supplymall.payment.dto.CallbackInputParameter;
import com.vogue.supplymall.payment.dto.CancelResultParameter;
import com.vogue.supplymall.payment.dto.IResultParameter;
import com.vogue.supplymall.payment.dto.PayCancelInputParameter;
import com.vogue.supplymall.payment.dto.PayQueryInputParameter;
import com.vogue.supplymall.payment.dto.PayQueryResultParameter;
import com.vogue.supplymall.payment.dto.ResultParameter;
import com.vogue.supplymall.payment.dto.ValidationDTO;

/**
 * 食尚购支付入口
 * 
 * @author 崔岳
 *
 */
@RestController
public class SharegoPayController extends BaseController {

	public static final Logger LOGGER_SHAREGOPAYCONTROLLER = LoggerFactory.getLogger(SharegoPayController.class);

	@DelegateResource
	private OrderUpdateBiz orderUpdateBiz;
	
	@DelegateResource
	private OrderService orderService;
	
	@DelegateResource
	private OrderSellerService orderSellerService;
	
	@DelegateResource
    private OrderPaymentService orderPaymentService;
    
	@Resource
    private WuXiangPayment wuXiangPayment;
    
    @Resource(name = "memProvider")
    private IMemProvider<Object> memProvider;
    
//	@Value("${pay.wuxiang.publickey}")
//	private String payWuxiangPublickey64 = null;
//
//	@Value("${pay.wuxiang.commPayGetUrl}")
//	private String payWuxiangCommPayGetUrl = null;
//
//	@Value("${pay.wuxiang.commPayCancelUrl}")
//	private String payWuxiangCommPayCancelUrl = null;
//
//	@Value("${pay.wuxiang.callBack.secretKey}")
//	private String payWuxiangCallbackSecretKey = null;
//	
//	@Value("${pay.wuxiang.stateQueryUrl}")
//	private String payWuxiangStateQueryUrl = null;

	@SuppressWarnings("unchecked")
    /**
	 * 支付成功回调接口
	 * 
	 * @param appver
	 * @param callbackInputParameter
	 * @return
	 */
	@RequestMapping(value = "/ns/{appver}/payment/sharego/paycallback", method = RequestMethod.POST)
	public ResponseEntity<Object> orderPayCallback(@PathVariable("appver") String appver,
			@RequestBody CallbackInputParameter callbackInputParameter) {
		LOGGER_SHAREGOPAYCONTROLLER.info("订单回到支付类型：{} 订单号：{}", callbackInputParameter.getPaytypeid(), callbackInputParameter.getOrderid());
		BaseResultParameter brp = new BaseResultParameter();
		brp.setErrorText("成功");
		brp.setReturnCode(1);
		brp.setErrorCode("200"); 
		try {
		    Map<String,Object> map = new HashMap<>();
            map.put("ordernumber", callbackInputParameter.getOrderid());
            FutureWrapper<Order> orderWrapper = FutureWrapper.wrapper( orderService, gt -> 
            {
                try {
                    gt.selectOneByWhr0("ordernumber=#{ordernumber}", map);
                } catch (Exception e) {
                    LOGGER_SHAREGOPAYCONTROLLER.error("订单{}支付回调异常：{}", callbackInputParameter.getOrderid(), e.getMessage());
                }
            }, Order.class);
            Order order = orderWrapper.get();
//            Order order = orderService.selectOneByWhr0("ordernumber=#{ordernumber}", map);
            if(order == null) {
                orderWrapper = FutureWrapper.wrapper( orderService, gt -> 
                {
                    try {
                        gt.load(Long.parseLong(callbackInputParameter.getOrderid()));
                    } catch (Exception e) {
                        LOGGER_SHAREGOPAYCONTROLLER.error("订单{}支付回调异常：{}", callbackInputParameter.getOrderid(), e.getMessage());
                    }
                }, Order.class);
                order = orderWrapper.get();
//                order = orderService.load(Long.parseLong(callbackInputParameter.getOrderid()));
            }   
            Long orderid = order.getId();
            FutureWrapper<OrderPayment> orderPaymentWrapper = FutureWrapper.wrapper( orderPaymentService, gt -> 
            {
                try {
                    gt.selectOneByWhr("orderid=" + orderid);
                } catch (Exception e) {
                    LOGGER_SHAREGOPAYCONTROLLER.error("订单{}支付回调异常：{}", callbackInputParameter.getOrderid(), e.getMessage());
                }
            }, OrderPayment.class);
            OrderPayment orderPayment = orderPaymentWrapper.get();
//            OrderPayment orderPayment = orderPaymentService.selectOneByWhr("orderid=" + order.getId());
            InterCachePayValues cachedPayValues = null;
            if (orderPayment.getMergeflag() + orderPayment.getTsflag() == 0) {
                cachedPayValues = (CachedPayValues) memProvider.get(ConstantBean.WUXIANG_CACHED_PAY_VALUES);
            } else {
                cachedPayValues = (CachedTsPayValues) memProvider.get(ConstantBean.WUXIANG_CACHED_TS_PAY_VALUES);
            }
            String secretKey = cachedPayValues.getPayWuxiangCallbackSecretKey();
            FutureWrapper<Integer> wrapper = FutureWrapper.wrapper( orderUpdateBiz, gt -> 
            {
                try {
                    gt.callBackFunction(callbackInputParameter, secretKey);
                } catch (Exception e) {
                    LOGGER_SHAREGOPAYCONTROLLER.error("订单{}支付回调异常：{}", callbackInputParameter.getOrderid(), e.getMessage());
                }
            }, Integer.class);
            wrapper.get();
//			orderUpdateBiz.orderPayCallback(callbackInputParameter, cachedPayValues.getPayWuxiangCallbackSecretKey());
			LOGGER_SHAREGOPAYCONTROLLER.info("支付成功信息:{}", callbackInputParameter.toString());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			LOGGER_SHAREGOPAYCONTROLLER.error("{}支付回调错误信息：{}", callbackInputParameter.toString(), e.getMessage());
			brp.setErrorText(e.getMessage());
			brp.setReturnCode(-1);
			brp.setErrorCode("500");
		}
		return new ResponseEntity<>(brp, HttpStatus.OK);
	}

	/**
	 * 撤销付款
	 * @param appver
	 * @param payCancelInputParameter
	 * @return
	 */
//	@RequestMapping(value = "/ns/{appver}/payment/sharego/paycancel", method = RequestMethod.POST)
	public ResponseEntity<Object> orderPayCancel(@PathVariable("appver") String appver,
			@RequestBody PayCancelInputParameter payCancelInputParameter) {
	    BaseResultParameter crp = null;
		try {
			if (payCancelInputParameter instanceof ValidationDTO) {
				payCancelInputParameter.validationProperty();
			}
			Map<String,Object> map = new HashMap<>();
            map.put("ordernumber", payCancelInputParameter.getOrderid());
            Order order = orderService.selectOneByWhr0("ordernumber=#{ordernumber}", map);
            if(order == null) {
                order = orderService.load(Long.parseLong(payCancelInputParameter.getOrderid()));
            }   
			OrderPayment orderPayment = orderPaymentService.selectOneByWhr("orderid=" + order.getId());
            InterCachePayValues cachedPayValues = null;
            if (orderPayment.getMergeflag() + orderPayment.getTsflag() == 0) {
                cachedPayValues = (CachedPayValues) memProvider.get(ConstantBean.WUXIANG_CACHED_PAY_VALUES);
            } else {
                cachedPayValues = (CachedTsPayValues) memProvider.get(ConstantBean.WUXIANG_CACHED_TS_PAY_VALUES);
            }
			crp = wuXiangPayment.commPayCancel(payCancelInputParameter, cachedPayValues.getPayWuxiangCommPayCancelUrl(), cachedPayValues.getPayWuxiangPublickey64());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			crp = new CancelResultParameter();
			crp.setReturnCode(-1);
			crp.setErrorText(e.getMessage());
			crp.setErrorCode("404");
			LOGGER_SHAREGOPAYCONTROLLER.error("Paycancel is error:" + e.toString());
		}
		ControllerResultInfo resultInfo = new ControllerResultInfo();
		if (HttpStatus.OK.toString().equals(crp.getErrorCode())) {
			resultInfo.setData(crp.getData());
			resultInfo.setResult(true);
			resultInfo.setMsg(crp.getErrorText());
		} else {
			resultInfo.setResult(false);
			resultInfo.setMsg(crp.getErrorText());
			try {				
				resultInfo.setCode(Integer.parseInt(crp.getErrorCode()));
			}catch(NumberFormatException nfex) {
				LOGGER_SHAREGOPAYCONTROLLER.error("错误编码转换失败返回的是[{}]无法转换",crp.getErrorCode());
			}	
		}
		return new ResponseEntity<>(resultInfo, HttpStatus.OK);
	}
	
	/**
	 * 订单支付状态查询接口
	 * @param appver
	 * @param payQueryInputParameter
	 * @return
	 */
	@SuppressWarnings("unchecked")
    @RequestMapping(value = "/ns/{appver}/payment/sharego/paystatequery", method = RequestMethod.POST)
	public ResponseEntity<Object> orderPayStateQuery(@PathVariable("appver") String appver,
			@RequestBody PayQueryInputParameter payQueryInputParameter) {
	    IResultParameter crp = null;
		try {
			if (payQueryInputParameter instanceof ValidationDTO) {
				payQueryInputParameter.validationProperty();
			}
			Map<String,Object> map = new HashMap<>();
			map.put("ordernumber", payQueryInputParameter.getOrderid());
            FutureWrapper<Order> orderWrapper = FutureWrapper.wrapper( orderService, gt -> 
            {
                try {
                    gt.selectOneByWhr0("ordernumber=#{ordernumber}", map);
                } catch (Exception e) {
                    LOGGER_SHAREGOPAYCONTROLLER.error("订单{}状态查询异常：{}", payQueryInputParameter.getOrderid(), e.getMessage());
                }
            }, Order.class);
            Order order = orderWrapper.get();
//            Order order = orderService.selectOneByWhr0("ordernumber=#{ordernumber}", map);
            if(order == null) {
                orderWrapper = FutureWrapper.wrapper( orderService, gt -> 
                {
                    try {
                        gt.load(Long.parseLong(payQueryInputParameter.getOrderid()));
                    } catch (Exception e) {
                        LOGGER_SHAREGOPAYCONTROLLER.error("订单{}状态查询异常：{}", payQueryInputParameter.getOrderid(), e.getMessage());
                    }
                }, Order.class);
                order = orderWrapper.get();
//                order = orderService.load(Long.parseLong(callbackInputParameter.getOrderid()));
            }   
//			Order order = orderService.selectOneByWhr0("ordernumber=#{ordernumber}", map);
//			if(order == null) {
//				order = orderService.load(Long.parseLong(payQueryInputParameter.getOrderid()));				
//			}	
			if(order != null) {
                payQueryInputParameter.setOrderid(order.getOrdernumber());
                Long orderid = order.getId();
                FutureWrapper<OrderSeller> orderSellerWrapper = FutureWrapper.wrapper( orderSellerService, gt -> 
                {
                    try {
                        gt.selectOneByWhr("orderid=" + orderid);
                    } catch (Exception e) {
                        LOGGER_SHAREGOPAYCONTROLLER.error("订单{}状态查询异常：{}", payQueryInputParameter.getOrderid(), e.getMessage());
                    }
                }, OrderSeller.class);
                OrderSeller seller =  orderSellerWrapper.get();
//                OrderSeller seller = orderSellerService.selectOneByWhr("orderid="+order.getId());
                if (seller.getMcid() == null) {
                    throw new Exception("缺少必要的mcid！");
                } else {
                    payQueryInputParameter.setStoreid(seller.getMcid());
                }   
                
                FutureWrapper<OrderPayment> orderPaymentWrapper = FutureWrapper.wrapper( orderPaymentService, gt -> 
                {
                    try {
                        gt.selectOneByWhr("orderid=" + orderid);
                    } catch (Exception e) {
                        LOGGER_SHAREGOPAYCONTROLLER.error("订单{}状态查询异常：{}", orderid, e.getMessage());
                    }
                }, OrderPayment.class);
                OrderPayment orderPayment = orderPaymentWrapper.get();
//                OrderPayment orderPayment = orderPaymentService.selectOneByWhr("orderid=" + order.getId());
                InterCachePayValues cachedPayValues = null;
                if (orderPayment.getMergeflag() + orderPayment.getTsflag() == 0) {
                    cachedPayValues = (CachedPayValues) memProvider.get(ConstantBean.WUXIANG_CACHED_PAY_VALUES);
                } else {
                    cachedPayValues = (CachedTsPayValues) memProvider.get(ConstantBean.WUXIANG_CACHED_TS_PAY_VALUES);
                }
                crp = wuXiangPayment.queryPayState(payQueryInputParameter, cachedPayValues.getPayWuxiangStateQueryUrl(), cachedPayValues.getPayWuxiangPublickey64());
            } else {
                throw new Exception("缺少订单信息"+payQueryInputParameter.getOrderid());
            }			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			crp = new PayQueryResultParameter();
			crp.setReturnCode(-1);
			crp.setErrorText(e.getMessage());
			crp.setErrorCode("404");
			LOGGER_SHAREGOPAYCONTROLLER.error("Querystate is error:{}", e.toString());
		}
		ControllerResultInfo resultInfo = new ControllerResultInfo();
		if (HttpStatus.OK.toString().equals(crp.getErrorCode())) {
			resultInfo.setData(crp.getData());
			resultInfo.setResult(true);
			resultInfo.setMsg(crp.getErrorText());
		} else {
			resultInfo.setResult(false);
			resultInfo.setMsg(crp.getErrorText());
			try {				
				resultInfo.setCode(Integer.parseInt(crp.getErrorCode()));
			}catch(NumberFormatException nfex) {
				LOGGER_SHAREGOPAYCONTROLLER.error("错误编码转换失败返回的是[{}]无法转换",crp.getErrorCode());
			}			
		}
		return new ResponseEntity<>(resultInfo, HttpStatus.OK);
	}
	
	@SuppressWarnings("unchecked")
    @RequestMapping(value = "/ns/{appver}/payment/test", method = RequestMethod.POST)
    public ResponseEntity<Object> test(@PathVariable("appver") String appver,
            @RequestBody PayQueryInputParameter payQueryInputParameter) {
//	    try {
//	        OrderDetailInfo orderDetailInfo = null;
//            FutureWrapper<Void> wrapper = FutureWrapper.wrapper( orderUpdateBiz, gt -> gt.orderPayClose(1L), Void.class );
//            wrapper.get();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
	    CallbackInputParameter callbackInputParameter = new CallbackInputParameter();
	    OrderInfo info = new OrderInfo();
	    String callbackSecretKey = null;
	    try {
            FutureWrapper<Integer> wrapper = FutureWrapper.wrapper( orderUpdateBiz, gt -> {
                try {
                    gt.payOnline(info, BigDecimal.ZERO);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }, Integer.class );
            wrapper.get();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
	}
}
